#include "fcsync.h"
#include "ui_fcsync.h"
#include <QFileDialog>
#include <QFile>
#include <QDateTime>
#include <QProgressDialog>
#include "logdialog.h"
#include "tip.h"

FcSync::FcSync(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::FcSync)
{
    ui->setupUi(this);

    QStringList headerList;
    headerList.append(tr("序号"));
    headerList.append(tr("文件名"));
    headerList.append(tr("大小"));
    headerList.append(tr("最后修改时间"));
    headerList.append(tr("状态"));
    headerList.append(tr("选择"));
    headerList.append(tr("状态"));
    headerList.append(tr("文件名"));
    headerList.append(tr("大小"));
    headerList.append(tr("最后修改时间"));
    ui->treeWidget->setHeaderLabels(headerList);
    ui->treeWidget->setColumnWidth(0, 60);
    ui->treeWidget->setColumnWidth(1, 100);
    ui->treeWidget->setColumnWidth(2, 50);
    ui->treeWidget->setColumnWidth(3, 220);
    ui->treeWidget->setColumnWidth(4, 40);
    ui->treeWidget->setColumnWidth(5, 50);
    ui->treeWidget->setColumnWidth(6, 40);
    ui->treeWidget->setColumnWidth(7, 100);
    ui->treeWidget->setColumnWidth(8, 50);
    ui->treeWidget->setColumnWidth(9, 220);

    connect(ui->treeWidget, SIGNAL(itemPressed(QTreeWidgetItem*,int)), this, SLOT(itemPressedSlot(QTreeWidgetItem*,int)));

    mklog();


}

FcSync::~FcSync()
{
    delete ui;
}

void FcSync::on_pushButton_clicked()
{
    QString path = QFileDialog::getExistingDirectory(NULL, "打开文件夹", "/home/ltf/Desktop");
    ui->file_text1->setText(path);
}

void FcSync::on_pushButton_2_clicked()
{
    QString path = QFileDialog::getExistingDirectory(NULL, "打开文件夹", "/home/ltf/Desktop");
    ui->file_text2->setText(path);
}

void FcSync::on_pushButton_6_clicked()
{
    ui->treeWidget->clear();
    path1 = ui->file_text1->text();
    path2 = ui->file_text2->text();
    anal.analy(path1, path2, ui);
}

void FcSync::on_pushButton_7_clicked()
{
    logDialog log;
    log.showlog();
}

void FcSync::on_pushButton_4_clicked()
{
    path1 = ui->file_text1->text();
    path2 = ui->file_text2->text();
    if (path1.contains(path2) || path2.contains(path1)) {
        QMessageBox:: StandardButton result = QMessageBox::information(NULL, "Tip", "路径被包含，无需操作,确认继续执行？",
                                 QMessageBox::Yes|QMessageBox::No, QMessageBox::No);
        switch (result)
        {
        case QMessageBox::No:
            return ;
        }
    }

    QStringList cur1 = anal.getFile(path1, NULL);
    QStringList cur2 = anal.getFile(path2, NULL);

    int count = 0;
    for (int i = 0; i < cur1.size(); i++) {
        if (!cur2.contains(cur1[i])) {
            count++;
        }
    }
    for (int i = 0; i < cur2.size(); i++) {
        if (!cur1.contains(cur2[i])) {
            count++;
        }
    }

    if (!count) {
        QMessageBox::information(NULL, "Tip", "无可备份内容, 请查看是否有冲突文件",
                                 QMessageBox::Yes, QMessageBox::Yes);
        return ;
    }

    QProgressDialog* dialog = new QProgressDialog(tr("File sync progress"), tr("Cancel"), 0, count, this);
    dialog->setWindowTitle(tr("Progress"));
    dialog->setWindowModality(Qt::WindowModal);
    dialog->show();
    count = 0;

    QDateTime *datetime=new QDateTime(QDateTime::currentDateTime());
    QString time = datetime->toString("yyyy-MM-dd hh:mm:ss ddd");
    QFile file("./log.txt");
    file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append);
    file.write(('\n'+time+": "+path1+" 双向同步 "+path2+'\n').toUtf8());
    for (int i = 0; i < cur1.size(); i++) {
        if (!cur2.contains(cur1[i])) {
            copyFileToPath(path1, cur1[i], path2);
            file.write((path2+" 添加 "+cur1[i]+'\n').toUtf8());
            count++;
            dialog->setLabelText(" 添加 "+cur1[i]);
            dialog->setValue(count);
            if(dialog->wasCanceled()) return;

            QTime time1;
            time1.start();
            while(time1.elapsed() < 100) {
                QCoreApplication::processEvents();//处理事件
            }
        }
    }
    for (int i = 0; i < cur2.size(); i++) {
        if (!cur1.contains(cur2[i])) {
            copyFileToPath(path2, cur2[i], path1);
            file.write((path1+" 添加 "+cur2[i]+'\n').toUtf8());
            count++;
            dialog->setLabelText(" 添加 "+cur2[i]);
            dialog->setValue(count);
            if(dialog->wasCanceled()) return ;

            QTime time1;
            time1.start();
            while(time1.elapsed() < 100) {
                QCoreApplication::processEvents();//处理事件
            }
        }
    }
    file.close();

    on_pushButton_6_clicked();
    tip a;
    a.show();
}


void FcSync::on_pushButton_3_clicked()
{
    path1 = ui->file_text1->text();
    path2 = ui->file_text2->text();
    if (path1.contains(path2) || path2.contains(path1)) {
        QMessageBox:: StandardButton result = QMessageBox::information(NULL, "Tip", "路径被包含，无需操作,确认继续执行？",
                                 QMessageBox::Yes|QMessageBox::No, QMessageBox::No);
        switch (result)
        {
        case QMessageBox::No:
            return ;
        }
    }

    QDateTime *datetime=new QDateTime(QDateTime::currentDateTime());
    QString time = datetime->toString("yyyy-MM-dd hh:mm:ss ddd");
    QFile file("./log.txt");
    file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append);
    file.write(('\n'+time+": "+path1+" 备份到 "+path2+'\n').toUtf8());

    QStringList cur1 = anal.getFile(path1, NULL);
    QStringList cur2 = anal.getFile(path2, NULL);

    int count = 0, flag = 0;
    for (int i = 0; i < cur1.size(); i++) {
        if (cur2.contains(cur1[i])) {
            if (md5.getFileMd5(path1+cur1[i]) == md5.getFileMd5(path2+cur1[i])) count++;
            else flag++;
        }
    }
    count = cur1.size()+cur2.size()-2*count-flag;
    if (!count) {
        QMessageBox::information(NULL, "Tip", "无可备份内容",
                                 QMessageBox::Yes, QMessageBox::Yes);
        return ;
    }

    if(count == 0) return ;
    QProgressDialog* dialog = new QProgressDialog(tr("File sync progress"), tr("Cancel"), 0, count, this);
    dialog->setMinimumDuration(0);
    dialog->setWindowTitle(tr("Progress"));
    dialog->setWindowModality(Qt::WindowModal);
    dialog->show();
    count = 0;

    for (int i = 0; i < cur1.size(); i++) {
        if (!cur2.contains(cur1[i])) {
            copyFileToPath(path1, cur1[i], path2);
            file.write((path2+" 添加 "+cur1[i]+'\n').toUtf8());

            dialog->setLabelText(" 添加 "+cur1[i]);
            count++;
            dialog->setValue(count);
            if(dialog->wasCanceled()) return ;

            QTime time1;
            time1.start();
            while(time1.elapsed() < 100) {
                QCoreApplication::processEvents();//处理事件
            }
        } else if (cur2.contains(cur1[i]) && md5.getFileMd5(path1+cur1[i]) != md5.getFileMd5(path2+cur1[i])) {
            copyFileToPath(path1, cur1[i], path2);
            file.write((path2+" 覆盖 "+cur1[i]+'\n').toUtf8());

            dialog->setLabelText(" 覆盖 "+cur1[i]);
            count++;
            dialog->setValue(count);
            if(dialog->wasCanceled()) return ;

            QTime time1;
            time1.start();
            while(time1.elapsed() < 100) {
                QCoreApplication::processEvents();//处理事件
            }
        }
    }
    for (int i = 0; i < cur2.size(); i++) {
        if (!cur1.contains(cur2[i])) {
            QFileInfo info(path2+cur2[i]);
            if (info.isDir()) {
                QDir dir(path2+cur2[i]);
                dir.removeRecursively();
            } else {
                QFile::remove(path2+cur2[i]);
            }
            file.write((path2+" 移除 "+cur2[i]+'\n').toUtf8());

            dialog->setLabelText(" 移除 "+cur2[i]);
            count++;
            dialog->setValue(count);
            if(dialog->wasCanceled()) return ;

            QTime time1;
            time1.start();
            while(time1.elapsed() < 100) {
                QCoreApplication::processEvents();//处理事件
            }
        }
    }
    file.close();

    on_pushButton_6_clicked();
}

void FcSync::on_pushButton_5_clicked()
{
    path1 = ui->file_text1->text();
    path2 = ui->file_text2->text();
    if (path1.contains(path2) || path2.contains(path1)) {
        QMessageBox:: StandardButton result = QMessageBox::information(NULL, "Tip", "路径被包含，无需操作,确认继续执行？",
                                 QMessageBox::Yes|QMessageBox::No, QMessageBox::No);
        switch (result)
        {
        case QMessageBox::No:
            return ;
        }
    }

    QDateTime *datetime=new QDateTime(QDateTime::currentDateTime());
    QString time = datetime->toString("yyyy-MM-dd hh:mm:ss ddd");
    QFile file("./log.txt");
    file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append);
    file.write(('\n'+time+": "+path2+" 备份到 "+path1+'\n').toUtf8());

    QStringList cur1 = anal.getFile(path1, NULL);
    QStringList cur2 = anal.getFile(path2, NULL);

    int count = 0, flag = 0;
    for (int i = 0; i < cur2.size(); i++) {
        if (cur1.contains(cur2[i])) {
            if (md5.getFileMd5(path1+cur2[i]) == md5.getFileMd5(path2+cur2[i])) count++;
            else flag++;
        }
    }
    count = cur1.size()+cur2.size()-2*count-flag;
    if (!count) {
        QMessageBox::information(NULL, "Tip", "无可备份内容",
                                 QMessageBox::Yes, QMessageBox::Yes);
        return ;
    }

    QProgressDialog* dialog = new QProgressDialog(tr("File sync progress"), tr("Cancel"), 0, count, this);
    dialog->setMinimumDuration(0);
    dialog->setWindowTitle(tr("Progress"));
    dialog->setWindowModality(Qt::WindowModal);
    dialog->show();
    count = 0;

    for (int i = 0; i < cur2.size(); i++) {
        if (!cur1.contains(cur2[i])) {
            copyFileToPath(path2, cur2[i], path1);
            file.write((path1+" 添加 "+cur2[i]+'\n').toUtf8());

            dialog->setLabelText(" 添加 "+cur2[i]);
            count++;
            dialog->setValue(count);
            if(dialog->wasCanceled()) return ;

            QTime time1;
            time1.start();
            while(time1.elapsed() < 100) {
                QCoreApplication::processEvents();//处理事件
            }
        } else if (cur1.contains(cur2[i]) && md5.getFileMd5(path1+cur2[i]) != md5.getFileMd5(path2+cur2[i])) {
            copyFileToPath(path2, cur2[i], path1);
            file.write((path1+" 覆盖 "+cur2[i]+'\n').toUtf8());

            dialog->setLabelText(" 覆盖 "+cur2[i]);
            count++;
            dialog->setValue(count);
            if(dialog->wasCanceled()) return ;

            QTime time1;
            time1.start();
            while(time1.elapsed() < 100) {
                QCoreApplication::processEvents();//处理事件
            }
        }
    }
    for (int i = 0; i < cur1.size(); i++) {
        if (!cur2.contains(cur1[i])) {
            QFileInfo info(path1+cur1[i]);
            if (info.isDir()) {
                QDir dir(path1+cur1[i]);
                dir.removeRecursively();
            } else {
                QFile::remove(path1+cur1[i]);
            }
            file.write((path1+" 移除 "+cur1[i]+'\n').toUtf8());

            dialog->setLabelText(" 移除 "+cur1[i]);
            count++;
            dialog->setValue(count);
            if(dialog->wasCanceled()) return ;

            QTime time1;
            time1.start();
            while(time1.elapsed() < 100) {
                QCoreApplication::processEvents();//处理事件
            }
        }
    }
    file.close();
    on_pushButton_6_clicked();
}

void FcSync::itemPressedSlot(QTreeWidgetItem * pressedItem, int column)
{
    path1 = ui->file_text1->text();
    path2 = ui->file_text2->text();
    if (path1 == "" || path2 == "" || path1 == path2) return ;

    if (path1.contains(path2) || path2.contains(path1)) {
        QMessageBox:: StandardButton result = QMessageBox::information(NULL, "Tip", "路径被包含，无需操作,确认继续执行？",
                                 QMessageBox::Yes|QMessageBox::No, QMessageBox::No);
        switch (result)
        {
        case QMessageBox::No:
            return ;
        }
    }

    QTreeWidgetItem* curItem=ui->treeWidget->currentItem();
    QString file1 = curItem->text(1);
    QString file2 = curItem->text(7);
    QString chose = curItem->text(column);
    if (column == 4 && chose != "") {
        copyFileToPath(path1, file1, path2);

        QString sourceDir = path1, File = file1, toDir = path2;
        QDateTime *datetime=new QDateTime(QDateTime::currentDateTime());
        QString time = datetime->toString("yyyy-MM-dd hh:mm:ss ddd");
        QFile file("./log.txt");
        file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append);
        file.write(('\n'+time+": "+toDir+File+" 覆盖，解决冲突 "+sourceDir+File+'\n').toUtf8());
        file.close();

    } else if (column == 6 && chose != "") {
        copyFileToPath(path2, file2, path1);

        QString sourceDir = path2, File = file2, toDir = path1;
        QDateTime *datetime=new QDateTime(QDateTime::currentDateTime());
        QString time = datetime->toString("yyyy-MM-dd hh:mm:ss ddd");
        QFile file("./log.txt");
        file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append);
        file.write(('\n'+time+": "+toDir+File+" 覆盖，解决冲突 "+sourceDir+File+'\n').toUtf8());
        file.close();

    } else {
        return ;
    }
    on_pushButton_6_clicked();
}

//
bool FcSync::copyFileToPath(const QString &sourceDir, const QString &File, const QString &toDir)
{
    QFileInfo info(sourceDir+File);
    if (info.isDir()) {
        QDir dir(toDir);
        dir.mkpath(toDir+File);
        return true;
    }

    //可注释
    QStringList cur = File.split('/');
    QString dir;
    for (int i = 0; i < cur.size()-1; i++) {
        dir.append("/"+cur[i]);
    }
    QDir dirto(toDir);
    dirto.mkpath(toDir+dir);
    QFile::remove(toDir+File);


    auto local = new QThread;
    auto worker = new FileCopyer(local);
    QObject::connect(worker, &FileCopyer::finished, [](bool s) {
        s ? qDebug() << "FINISHED" : qDebug() << "FAILED";
    });
    QObject::connect(worker, &FileCopyer::copyProgress, [](qint64 copy, qint64 total) {
        qDebug() << QStringLiteral("PROGRESS => %1").arg(qreal(copy) / qreal(total) * 100.0);
    });
    QVector<QString> ve1, ve2;
    ve1.append(sourceDir+File); ve2.append(toDir+File);
    worker->setSourcePaths(ve1) ; // e.g: ~/content/example.mp4
    worker->setDestinationPaths(ve2); // e.g /usr/local/example.mp4
    local->start();
    /*if(!QFile::copy(sourceDir+File, toDir+File))
    {
        qDebug() <<sourceDir+File << "  " << toDir+File << endl;
        return false;
    }*/
    return true;
}

//拷贝文件夹：
bool FcSync::copyDirectoryFiles(const QString &fromDir, const QString &toDir, bool coverFileIfExist)
{
    QDir sourceDir(fromDir);
    QDir targetDir(toDir);
    if (!targetDir.exists()) {    // 如果目标目录不存在，则进行创建
        if (!targetDir.mkdir(targetDir.absolutePath()))
            return false;
    }

    QFileInfoList fileInfoList = sourceDir.entryInfoList();
    foreach (QFileInfo fileInfo, fileInfoList) {
        if (fileInfo.fileName() == "." || fileInfo.fileName() == "..")
            continue;

        if (fileInfo.isDir()) {    // 当为目录时，递归的进行copy
            if(!copyDirectoryFiles(fileInfo.filePath(),
                targetDir.filePath(fileInfo.fileName()),
                coverFileIfExist))
                return false;
        } else {            // 当允许覆盖操作时，将旧文件进行删除操作
            if (coverFileIfExist && targetDir.exists(fileInfo.fileName())) {
                targetDir.remove(fileInfo.fileName());
            }

            /// 进行文件copy
            if (!QFile::copy(fileInfo.filePath(),
                targetDir.filePath(fileInfo.fileName()))) {
                    return false;
            }
        }
    }
    return true;
}


bool FcSync::clearDir(QString path)
{
    if (path.isEmpty())
    {
        return false;
    }

    QDir dir(path);
    if (!dir.exists())
    {
        return false;
    }

    dir.setFilter(QDir::AllEntries | QDir::NoDotAndDotDot); //设置过滤

    QFileInfoList fileList = dir.entryInfoList(); // 获取所有的文件信息

    //遍历文件信息
    foreach (QFileInfo file, fileList)
    {
        // 是文件，删除
        if (file.isFile())
        {
            file.dir().remove(file.fileName());
        }
        else // 递归删除
        {
            clearDir(file.absoluteFilePath());
            file.dir().rmdir(file.absoluteFilePath());
        }
    }

    return true;
}

void FcSync::mklog()
{
    QFile file("./log.txt");
    if (!file.exists()) {
        file.open( QIODevice::ReadWrite | QIODevice::Text | QIODevice::Append);
        file.close();
    }
}
